﻿using System;
using System.Collections.Generic;

namespace Takkou.Core
{
    public enum TerrainType
    {
        GRASS = 0,
        STONE, 
        WATER,
    }

    public class World
    {
        public int Width { get; private set; }
        public int Height { get; private set; }
        
        /** Elements (robot, keys, etc) in the world */
        private Dictionary<string, WorldElement> elements;

        /** World grid */
        private TerrainType[,] terrain;

        /**
         * Create a world with dimensions width x height and data 'ter', where 'ter' is a comma-separated string
         * which values correspond to the enum TerrainType values. This string creates a tile-based world.
         */
        public World(int width, int height, string ter)
        {
            Width = width;
            Height = height;
            elements = new Dictionary<string, WorldElement>();
            terrain = new TerrainType[width, height];
            char[] separators = {' ', ',', '\n'};
            string[] str = ter.Split(separators, StringSplitOptions.RemoveEmptyEntries);
            for (int x = 0; x < width; x++)
                for (int y = 0; y < height; y++)
                    terrain[x, y] = (TerrainType) Int16.Parse(str[y * height + x]);
        }

        /**
         * Add a new world element. It should be used when initializing the world,
         * a new bulding is created or a new user enter in the world.
         */
        public bool addWorldElement(WorldElement e)
        {
            try
            {
                elements.Add(e.ID, e);
                return true;
            }
            catch (ArgumentException exc)
            {   // probably the element already exists
                return false;
            }
        }

        /**
         * Remove a element from the world. It should be used when the element is destroyed
         * or a user is disconnected.
         */
        public bool removeWorldElement(WorldElement e)
        {
            return elements.Remove(e.ID);
        }

        /**
         * Consult a world element according to its name
         */
        public WorldElement getWorldElement(string id)
        {
            WorldElement we;
            elements.TryGetValue(id, out we);
            return we;
        }

        /** Returns a collection with the set of elements in the world */
        public Dictionary<string, WorldElement>.ValueCollection getElements()
        {
            return elements.Values;
        }

        /** Check the terrain type at a given tile position */
        public TerrainType terrainAt(int x, int y)
        {
            return terrain[x, y];
        }
    }
}
